﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Web;
using System.Web.Script.Serialization;

namespace KL.Store.Core.Contact
{

    public class MsnContact
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
    }

    public class MsnContactService
    {
        private const string wlCookie = "wl_auth";
        //private const string clientId = ;
        private string Callback = "http://localstore.com/Contact/Msn";
        //private const string clientSecret = ;
        private const string oauthUrl = "https://oauth.live.com/token";
        private List<MsnContact> contactList = new List<MsnContact>();
        public MsnContactService()
        {

        }

        public List<MsnContact> GetMsnContacts(string code)
        {
            try
            {
                HttpContext context = HttpContext.Current;
                string verifier = code;
                OAuthToken token;
                OAuthError error;

                if (!string.IsNullOrEmpty(verifier))
                {
                    RequestAccessTokenByVerifier(verifier, out token, out error);
                }
            }
            catch //(Exception ex)
            {
                
            }
            return contactList;
        }
        private void RequestAccessTokenByVerifier(string verifier, out OAuthToken token, out OAuthError error)
        {
            string content = String.Format("client_id={0}&redirect_uri={1}&client_secret={2}&code={3}&grant_type=authorization_code",
            System.Web.HttpUtility.UrlEncode(Core.Parameters.MsnClientID),
            System.Web.HttpUtility.UrlEncode(Callback),
            System.Web.HttpUtility.UrlEncode(Core.Parameters.MsnSecretKey),
            System.Web.HttpUtility.UrlEncode(verifier));
            RequestAccessToken(content, out token, out error);
        }
        private void RequestAccessToken(string postContent, out OAuthToken token, out OAuthError error)
        {
            token = null;
            error = null;
            HttpWebRequest request = WebRequest.Create(oauthUrl) as HttpWebRequest;
            request.Method = "POST";
            try
            {
                using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                {
                    writer.Write(postContent);
                }
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                if (response != null)
                {
                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(OAuthToken));
                    token = serializer.ReadObject(response.GetResponseStream()) as OAuthToken;
                    if (token != null)
                    {
                        RequestContacts(token.AccessToken);
                    }
                }
            }
            catch // (Exception ex)
            {

            }

        }
        private void RequestContacts(string AccessToken)
        {
            string content = String.Format("access_token={0}", System.Web.HttpUtility.UrlEncode(AccessToken));
            string url = "https://apis.live.net/v5.0/me/contacts?" + content;
            //string url = "https://apis.live.net/v5.0/me/contacts?access_token=&#8221; + AccessToken;
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            //request.Method = "POST";
            request.Method = WebRequestMethods.Http.Get;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream());
            string tmp = reader.ReadToEnd();
            JavaScriptSerializer ser = new JavaScriptSerializer();
            Dictionary<string, object> dictionary = ser.Deserialize<Dictionary<string, object>>(tmp);
            FillContactList(dictionary);
        }
        public List<MsnContact> FillContactList(Dictionary<string, object> dict)
        {
            foreach (var item in ((ArrayList)dict["data"]))
            {
                Dictionary<string, object> dictObj = ((Dictionary<string, object>)item);
                if (dictObj["name"] != null && dictObj["name"].ToString().Contains("@"))
                {
                    contactList.Add(new MsnContact
                    {
                        Email = dictObj["name"] != null ? dictObj["name"].ToString() : string.Empty,
                        FirstName = dictObj["first_name"] != null ? dictObj["first_name"].ToString() : string.Empty,
                        LastName = dictObj["last_name"] != null ? dictObj["last_name"].ToString() : string.Empty
                    });
                }
            }

            return contactList;
        }

        public bool DisplayDictionary(Dictionary<string, object> dict)
        {
            bool bSuccess = false;
            string abc = string.Empty;
            MsnContact msnContact = new MsnContact();
            foreach (string strKey in dict.Keys)
            {
                string strOutput = "";// "".PadLeft(indentLevel * 8) + strKey + ":";
                object o = dict[strKey];
                if (o is Dictionary<string, object>)
                {
                    DisplayDictionary((Dictionary<string, object>)o);
                }
                else if (o is ArrayList)
                {
                    foreach (object oChild in ((ArrayList)o))
                    {
                        if (oChild is string)
                        {
                            strOutput = ((string)oChild);
                        }
                        else if (oChild is Dictionary<string, object>)
                        {
                            DisplayDictionary((Dictionary<string, object>)oChild);
                        }
                    }
                }
                else
                {
                    if (o != null)
                    {
                        strOutput = o.ToString();
                        if (strKey == "name")
                        {
                            if (strOutput.Contains("@"))
                                msnContact.Email = strOutput;
                            //contactList.Add(new MsnContact { Email = strOutput });
                        }
                        else if (strKey == "first_name")
                        {
                            msnContact.FirstName = strOutput;
                        }
                        else if (strKey == "last_name")
                        {
                            msnContact.LastName = strOutput;
                        }
                    }
                }
            }
            contactList.Add(msnContact);
            return bSuccess;
        }
    }

    [DataContract]
    public class OAuthToken
    {
        [DataMember(Name = OAuthConstants.AccessToken)]
        public string AccessToken { get; set; }
        [DataMember(Name = OAuthConstants.RefreshToken)]
        public string RefreshToken { get; set; }
        [DataMember(Name = OAuthConstants.ExpiresIn)]
        public string ExpiresIn { get; set; }
        [DataMember(Name = OAuthConstants.Scope)]
        public string Scope { get; set; }
    }

    public static class OAuthConstants
    {
        public const string ClientID = "client_id";
        public const string ClientSecret = "client_secret";
        public const string Callback = "redirect_uri";
        public const string ClientState = "state";
        public const string Scope = "scope";
        public const string Code = "code";
        public const string AccessToken = "access_token";
        public const string ExpiresIn = "expires_in";
        public const string RefreshToken = "refresh_token";
        public const string ResponseType = "response_type";
        public const string GrantType = "grant_type";
        public const string Error = "error";
        public const string ErrorDescription = "error_description";
        public const string Display = "display";
    }

    [DataContract]
    public class OAuthError
    {
        public OAuthError(string code, string desc)
        {
            this.Code = code;
            this.Description = desc;
        }
        [DataMember(Name = OAuthConstants.Error)]
        public string Code { get; private set; }
        [DataMember(Name = OAuthConstants.ErrorDescription)]
        public string Description { get; private set; }
    }

}
